package cc.catface.service;

import cc.catface.common.output.Result;
import cc.catface.dao.biz.app.*;
import cc.catface.dao.biz.app.dto.*;
import cc.catface.dao.biz.app.mapper.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class ApArticleServiceImpl implements ApArticleService {
    @Autowired
    private ApArticleMapperServiceImpl apArticleMapperService;
    @Autowired
    private ApArticleConfigMapperServiceImpl apArticleConfigMapperService;
    @Autowired
    private ApArticleContentMapperServiceImpl apArticleContentMapperService;
    @Autowired
    private ApUserMapperServiceImpl apUserMapperService;
    @Autowired
    private ApCommentMapperServiceImpl apCommentMapperService;
    @Autowired
    private ApCommentRepayMapperServiceImpl apCommentRepayMapperService;
    @Autowired
    private BaseService baseService;

    @Override
    public Result<AddArticleOUTDTO> addArticle(AddArticleINDTO in) {
        AddArticleINDTO.Article articleIn = in.getApArticle();
        ApUser user = apUserMapperService.getOne(new QueryWrapper<ApUser>().eq("phone", articleIn.getPhone()));
        if (user == null) return Result.error("未查询到用户");
        Long userId = user.getId();
        ApArticle article = new ApArticle();
        article.setTitle(articleIn.getTitle());
        article.setUserId(userId);
        article.setUserName(articleIn.getUserName());
        article.setChannelId(articleIn.getChannelId());
        article.setChannelName(articleIn.getChannelName());
        article.setLabels(articleIn.getLabels());
        article.setLayout(articleIn.getLayout());
        article.setFlag(articleIn.getFlag());
        article.setImages(articleIn.getImages());
        article.setProvinceId(articleIn.getProvinceId());
        article.setCityId(articleIn.getCityId());
        article.setCountyId(articleIn.getCountyId());
        article.setCreatedTime(articleIn.getCreatedTime());
        article.setPublishTime(article.getPublishTime());
        article.setOverview(articleIn.getOverview());
        AddArticleINDTO.Config configIn = in.getApArticleConfig();
        ApArticleConfig config = new ApArticleConfig();
        config.setIsComment(configIn.getIsComment());
        config.setIsForward(configIn.getIsForward());
        AddArticleINDTO.Content contentIn = in.getApArticleContent();
        ApArticleContent content = new ApArticleContent();
        content.setContent(contentIn.getContent());
        article.setId(null);
        //存ap_article
        article.setCreatedTime(in.getApArticle().getCreatedTime());
        apArticleMapperService.save(article);
        log.info("保存文章, articleId:{}", article.getId());
        //存ap_article_config
        config.setArticleId(article.getId());
        apArticleConfigMapperService.save(config);
        //存ap_article_content
        content.setArticleId(article.getId());
        apArticleContentMapperService.save(content);

        AddArticleOUTDTO out = new AddArticleOUTDTO();
        out.setArticleId(article.getId());
        return Result.success(out);
    }

    @Override
    public Result<List<ArticleCommentOUTDTO>> articleComment(ArticleCommentINDTO in) {
        ApArticle article = apArticleMapperService.getOne(new QueryWrapper<ApArticle>().eq("id", in.getArticleId()));
        if (article == null) return Result.error("未查询到文章或动态");
        List<ApComment> comments = apCommentMapperService.list(new QueryWrapper<ApComment>().eq("article_id", in.getArticleId()));
        if (comments == null || comments.size() < 1) return Result.success(null);
        List<ArticleCommentOUTDTO> outs = new ArrayList<>();
        comments.sort((o1, o2) -> (int) (o2.getCreatedTime().getTime() - o1.getCreatedTime().getTime()));
        for (ApComment c : comments) {
            ArticleCommentOUTDTO out = new ArticleCommentOUTDTO();
            out.setCommentId(c.getId());
            out.setUserName(baseService.getUserByUserId(c.getUserId()).getName());
            out.setContent(c.getContent());
            out.setImageUrl(c.getImage());
            out.setAddress(c.getAddress());
            out.setCreatedTime(c.getCreatedTime());
            long commentId = c.getId();
            List<ArticleCommentOUTDTO.Repay> repayOuts = new ArrayList<>();
            List<ApCommentRepay> repays = apCommentRepayMapperService.list(new QueryWrapper<ApCommentRepay>().eq("comment_id", commentId));
            if (repays != null && repays.size() > 0) {
                repays.sort((o1, o2) -> (int) (o2.getCreatedTime().getTime() - o1.getCreatedTime().getTime()));
                for (ApCommentRepay r : repays) {
                    ArticleCommentOUTDTO.Repay repayOut = new ArticleCommentOUTDTO.Repay();
                    repayOut.setRepayId(r.getId());
                    repayOut.setUserName(baseService.getUserByUserId(r.getUserId()).getName());
                    repayOut.setContent(r.getContent());
                    repayOut.setAddress(r.getAddress());
                    repayOut.setCreatedTime(r.getCreatedTime());
                    repayOuts.add(repayOut);
                }
            }
            out.setRepays(repayOuts);
            outs.add(out);
        }
        return Result.success(outs);
    }

    @Override
    public Result<GetContentOUTDTO> getContent(GetContentINDTO in) {
        //文章阅读量+1
        ApArticle article = apArticleMapperService.getOne(new QueryWrapper<ApArticle>().eq("id", in.getArticleId()));
        if (article == null) return Result.error("未查询到详细文章内容");
        long views = article.getViews();
        apArticleMapperService.update(new UpdateWrapper<ApArticle>().eq("id", in.getArticleId()).set("views", ++views));
        //查详细文章内容
        ApArticleContent one = apArticleContentMapperService.getOne(new QueryWrapper<ApArticleContent>().eq("article_id", in.getArticleId()));
        if (one == null) return Result.error("未查询到详细文章内容");
        GetContentOUTDTO out = new GetContentOUTDTO();
        out.setContent(one.getContent());
        return Result.success(out);
    }

    @Override
    public Result<ListByChannelIdOUTDTO> listByChannelId(ListByChannelIdINDTO in) {
        //分页
        Page<ApArticle> page = new Page<>();
        page.setCurrent(in.getPage());
        page.setSize(in.getPageSize());
        Page<ApArticle> ds = apArticleMapperService.page(page, new QueryWrapper<ApArticle>().eq("channel_id", in.getChannelId()));
        List<ApArticle> records = ds.getRecords();
        //按发布时间倒序排序
        //records = records.stream().sorted(Comparator.comparingInt(o -> DateUtil.second(o.getPublishTime()))).collect(Collectors.toList());
        records = records.stream().sorted(Comparator.comparingLong(ApArticle::getId)).collect(Collectors.toList());
        Collections.reverse(records);
        List<ListByChannelIdOUTDTO.ArticleDetail> articleDetails = new ArrayList<>();
        //添加文章配置和内容对象
        records.forEach(apArticle -> {
            Long articleId = apArticle.getId();
            ListByChannelIdOUTDTO.ArticleDetail articleDetail = new ListByChannelIdOUTDTO.ArticleDetail();
            articleDetail.setApArticle(apArticle);
            articleDetail.setApArticleConfig(apArticleConfigMapperService.getOne(new QueryWrapper<ApArticleConfig>().eq("article_id", articleId)));
            //articleDetail.setApArticleContent(apArticleContentMapperService.getOne(new QueryWrapper<ApArticleContent>().eq("article_id", articleId)));
            articleDetails.add(articleDetail);

        });
        //组装出参
        ListByChannelIdOUTDTO out = new ListByChannelIdOUTDTO();
        out.setTotal(ds.getTotal());
        out.setPage(ds.getCurrent());
        out.setPageSize(ds.getSize());
        out.setArticleDetail(articleDetails);
        return Result.success(out);
    }
}
